package com.zmn.plat.admin.controller.product.tariff;

import java.math.BigDecimal;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.zmn.plat.model.vo.product.tariff.item.ProductTariffGroupItemVo;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.google.common.collect.Maps;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto.KvDTO;
import com.zmn.common.utils.math.MathUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.office.excel.ExportExcel;
import com.zmn.common.utils.response.ResponseUtil;
import com.zmn.plat.common.constant.ProductConsts;
import com.zmn.plat.manager.dictionary.MasterDict;
import com.zmn.plat.manager.dictionary.ProductDict;
import com.zmn.plat.model.entity.category.BaseCategory;
import com.zmn.plat.model.entity.channel.Channel;
import com.zmn.plat.model.entity.channel.ChannelQuery;
import com.zmn.plat.model.entity.product.ServProduct;
import com.zmn.plat.model.entity.product.ServProductQuery;
import com.zmn.plat.model.entity.product.tariff.ProductTariffQuery;
import com.zmn.plat.model.entity.servcategory.ServAssCategoryQuery;
import com.zmn.plat.model.entity.servcategory.ServCategory;
import com.zmn.plat.model.entity.service.tariff.ServiceTariff;
import com.zmn.plat.model.vo.product.tariff.ProductTariffExportVO;
import com.zmn.plat.model.vo.product.tariff.ProductTariffVO;
import com.zmn.plat.model.vo.servcategory.ServAssCategoryVO;

/**
 * 产品故障价格表，每个产品价格表一条数据，配置价格表说明、状态等
 *
 * @author linfeng
 * @since 2019-11-21 18:57:24
 */
@RequestMapping("/product/tariff/")
@Controller
public class ProductTariffListController extends ProductTariffBaseController {
    /**
     * 列表
     *
     * @param query
     * @author tanbiao
     * @since 2019-11-21 18:57:24
     */
    @RequestMapping("list")
    @RequiresPermissions("/product/tariff/list.action")
    public ModelAndView list(@ModelAttribute ProductTariffQuery query) {

        // 默认查询上架
        if (query.getProductStatus() == null) {
            query.setProductStatus(GlobalConsts.YES);
        }
        List<ProductTariffVO> items = productFaultTariffService.listPageByQuery(query);
        ServCategory querySC = new ServCategory();
        // 服务分类
        List<ServCategory> servCategories = servCategoryService.listByQuery(querySC);
        List<BaseCategory> baseCategories = Collections.emptyList();
        if (NumberUtil.isPositiveInteger(query.getServCategId())) {
            baseCategories =
                servAssCategoryService.findCategoryOneByServIdAndShowType(query.getServCategId(), ProductDict.ERP_PRODUCT_TYPE);
        }

        List<ServAssCategoryVO> baseCategoryTwoList = Collections.emptyList();
        if (NumberUtil.isPositiveInteger(query.getCategOneId())) {
            ServAssCategoryQuery queryBQ = new ServAssCategoryQuery();
            queryBQ.setServCategId(query.getServCategId());
            queryBQ.setCategOneId(query.getCategOneId());
            queryBQ.setShowType(ProductDict.ERP_PRODUCT_TYPE);
            baseCategoryTwoList = servAssCategoryService.listByQuery(queryBQ);
        }

        // 二级渠道
        ChannelQuery channelQuery = new ChannelQuery();
        channelQuery.setRank(2);
        List<Channel> channelLevelTwos = channelService.listByQuery(channelQuery);
        ServiceTariff faultTariff = faultTariffService.findByKey(query.getTariffId());
        ModelAndView mav = new ModelAndView("product/service/tariff/list");
        mav.addObject("items", items);
        mav.addObject("vo", query);
        mav.addObject("servCategories", servCategories);
        mav.addObject("baseCategories", baseCategories);
        mav.addObject("baseCategoryTwoList", baseCategoryTwoList);
        mav.addObject("channelLevelTwos", channelLevelTwos);
        mav.addObject("faultTariff", faultTariff);
        mav.addObject("flag", query.getFlag());

        return mav;
    }

    /**
     * 描述: 跳转到添加价格表页面：保内保外不区分功能权限：产品经理：陈燕
     *
     * @param productId
     *            产品id
     * @return org.springframework.web.servlet.ModelAndView
     * @author linfeng
     * @since 201911/27
     **/
    @RequestMapping(value = "addEditProductPrice")
    @RequiresPermissions("/product/tariff/addEditProductPrice.action")
    public ModelAndView addEditProductPrice(@RequestParam(value = "productId") Integer productId,
        @RequestParam(value = "tariffId", defaultValue = "0") Integer tariffId) {

        ModelAndView mv = new ModelAndView("product/service/tariff/modify");
        ServiceTariff faultTariff = faultTariffService.findByKey(tariffId);
        baseAddEditProductPrice(mv, productId, tariffId, faultTariff.getBizType());
        return mv;
    }

    /**
     * 描述: 初始化产品列表
     *
     * @param categOneId
     *            一级产品类型ID
     * @param servCategId
     *            服务ID
     */
    @RequestMapping("listProduct")
    @SuppressWarnings("Duplicates")
    public void listProduct(HttpServletRequest request, HttpServletResponse response,
        @RequestParam(value = "servCategId", defaultValue = "1") int servCategId,
        @RequestParam(value = "categOneId", defaultValue = "1") int categOneId) {
        ServProductQuery servProductQuery = new ServProductQuery();
        servProductQuery.setServCategId(servCategId);
        servProductQuery.setCategOneId(categOneId);
        servProductQuery.setShowType(ProductConsts.ERP_PRODUCT_TYPE);
        servProductQuery.setStatus(GlobalConsts.YES);
        List<ServProduct> servProductList = servProductService.listByQuery(servProductQuery);

        StringBuilder sb = new StringBuilder("[");
        String jsonFormat = "[\"%s\",\"%s\"]%s ";

        for (int i = 0; i < servProductList.size(); i++) {
            ServProduct item = servProductList.get(i);
            sb.append(String.format(jsonFormat, item.getProductId(), item.getName(), (i == servProductList.size() - 1 ? "" : ",")));
        }
        sb.append("]");

        ResponseUtil.outWrite(response, sb.toString());
    }

    /**
     * 描述: 分类联动（服务分类查询一级产品分类）
     *
     * @param response
     *            响应
     * @param serviceCategoryId
     *            服务分类id
     * @author linfeng
     * @since 2019/11/30
     **/
    @RequestMapping("loadListChilds")
    @SuppressWarnings("Duplicates")
    public void loadListChilds(HttpServletResponse response,
        @RequestParam(value = "parentId", defaultValue = "1") Integer serviceCategoryId) {

        if (serviceCategoryId <= 0) {
            ResponseUtil.outWrite(response, "[]");
            return;
        }
        ServAssCategoryQuery build = ServAssCategoryQuery.builder().servCategId(serviceCategoryId).categOneStatus(GlobalConsts.YES)
            .showType(ProductDict.ERP_PRODUCT_TYPE).build();
        List<KvDTO<Integer, String>> items = servAssCategoryService.listCateOneByQuery(build);
        StringBuilder sb = new StringBuilder("[");
        String jsonFormat = "[\"%s\",\"%s\"]%s ";

        for (int i = 0; i < items.size(); i++) {
            KvDTO<Integer, String> item = items.get(i);
            sb.append(String.format(jsonFormat, item.getKey(), item.getValue(), (i == items.size() - 1 ? "" : ",")));
        }
        sb.append("]");

        ResponseUtil.outWrite(response, sb.toString());
    }

    @RequestMapping(value = "exportExcel")
    @RequiresPermissions("/product/tariff/exportExcel.action")
    public void exportExcel(HttpServletResponse response, ProductTariffQuery query) {
        Integer pageSize = getExportPageLimit(response);
        query.setPageSize(pageSize);

        List<ProductTariffExportVO> faultExportList = productFaultTariffService.listExportExcelPageByQuery(query);
        if (CollectionUtils.isEmpty(faultExportList)) {
            faultExportList = new ArrayList<>();
            faultExportList.add(new ProductTariffExportVO());
        } else {
            faultExportList.forEach(e -> {
                e.setPrice(narrow(e.getPrice()));
                e.setInternalSettlementPrice(narrow(e.getInternalSettlementPrice()));
                e.setExternalSettlementPrice(narrow(e.getExternalSettlementPrice()));
                e.setTrafficFee(narrow(e.getTrafficFee()));
                e.setHourFee(narrow(e.getHourFee()));
                e.setCheckFee(narrow(e.getCheckFee()));
                e.setServicePrice(narrow(e.getServicePrice()));
                e.setPartPrice(narrow(e.getPartPrice()));
                e.setArtPrice("");
                e.setGuaranteePrice("");
                calPriceTable(e);
            });
        }

        // 封装Excel对象
        LinkedHashMap<String, String> fieldMap = Maps.newLinkedHashMap();
        fieldMap.put("tariffId", "价格表ID");
        fieldMap.put("tariffName", "价格表名称");
        fieldMap.put("tariffType", "价格表类型");
        fieldMap.put("bizType", "业务类型");
        fieldMap.put("servCategName", "服务分类");
        fieldMap.put("categOneName", "一级产品分类");
        fieldMap.put("categTwoName", "二级产品分类");
        fieldMap.put("productId", "产品ID");
        fieldMap.put("productName", "产品名称");
        fieldMap.put("productStatus", "产品状态");
        fieldMap.put("groupId", "项目分组ID");
        fieldMap.put("groupName", "项目分组名称");
        fieldMap.put("itemId", "项目ID");
        fieldMap.put("itemName", "项目名称");
        fieldMap.put("price", "销售价");
        fieldMap.put("internalSettlementPrice", "内部结算价");
        fieldMap.put("externalSettlementPrice", "外部结算价");
        fieldMap.put("priceSplit", "区分明细");
        fieldMap.put("trafficFee", "交通费");
        fieldMap.put("hourFee", "工时费");
        fieldMap.put("artPrice", "工艺费");
        fieldMap.put("guaranteePrice", "保修费");
        fieldMap.put("checkFee", "检测费");
        fieldMap.put("servicePrice", "技术服务费");
        fieldMap.put("partPrice", "配件包干费");
        fieldMap.put("priceStandard", "一口价");
        fieldMap.put("unit", "单位");
        fieldMap.put("countLimit", "最大数量");
        fieldMap.put("itemGeneral", "默认项目");
        fieldMap.put("mutexMode", "互斥性");
        fieldMap.put("cityLimit", "城市系数");
        fieldMap.put("brandLimit", "品牌系数");
        fieldMap.put("categName", "项目类型");
        fieldMap.put("takePicture", "工程师拍照");
        fieldMap.put("afterService", "是否保修");
        fieldMap.put("afterServiceDesc", "保修范围");
        fieldMap.put("afterServiceDay", "保修天数");
        fieldMap.put("faultItemStatus", "项目状态");

        try {
            ExportExcel<ProductTariffExportVO> excel = new ExportExcel<>(faultExportList, fieldMap, true);
            excel.exportExcel(response, "产品价格表");
        } catch (Exception e) {
            logger.error("导出报表出错" + e.getMessage(), e);
        }
    }

    /**
     * 描述: 将数据缩小100保留2位小数
     *
     * @param dividend
     *            被除数
     * @return double
     * @author linfeng
     * @since 10:36 2019/11/30
     **/
    private String narrow(Object dividend) {
        if (Objects.isNull(dividend)) {
            return "";
        }
        double div = MathUtil.div(Integer.parseInt(dividend.toString()), MasterDict.COEFFICIENT_MAGNIFICATION, 2);
        BigDecimal b = new BigDecimal(div);
        return b.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    }

    private void calPriceTable(ProductTariffExportVO vo){
        // 明细1 一口价区分明细计算价格
        if(Objects.equals(vo.getPriceStandard(),"一口价")
                &&Objects.equals(vo.getPriceSplit(),"区分")&&Objects.equals(vo.getPriceSplitType(),GlobalConsts.NO)&&Objects.nonNull(vo.getPrice())){
            BigDecimal onehundred = new BigDecimal(GlobalConsts.MONEY_YUAN_FEN_RATE);
            BigDecimal artRatio = Objects.isNull(vo.getArtRatio())?BigDecimal.ZERO:vo.getArtRatio().divide(onehundred);
            BigDecimal guaranteeRatio = Objects.isNull(vo.getGuaranteeRatio())?BigDecimal.ZERO:vo.getGuaranteeRatio().divide(onehundred);
            BigDecimal partRatio =  Objects.isNull(vo.getPartRatio())?BigDecimal.ZERO:vo.getPartRatio().divide(onehundred);
            Integer fee = new BigDecimal(vo.getHourFee()).add(new BigDecimal(vo.getTrafficFee())).add(new BigDecimal(vo.getCheckFee())).intValue();
            // 销售价
            BigDecimal price = new BigDecimal(vo.getPrice());
            // 配件费
            BigDecimal partRatioPrice = price.multiply(partRatio);
            BigDecimal artRatioPrice = price.multiply(artRatio);
            BigDecimal guaranteeRatioPrice = price.multiply(guaranteeRatio);
            // 技术服务费
            BigDecimal tecPrice = price.subtract(partRatioPrice).subtract(artRatioPrice).subtract(guaranteeRatioPrice).subtract(new BigDecimal(fee));

            vo.setPartPrice(partRatioPrice.setScale(2, BigDecimal.ROUND_HALF_UP).toString());
            vo.setArtPrice(artRatioPrice.setScale(2, BigDecimal.ROUND_HALF_UP).toString());
            vo.setGuaranteePrice(guaranteeRatioPrice.setScale(2, BigDecimal.ROUND_HALF_UP).toString());
            vo.setServicePrice(tecPrice.setScale(2, BigDecimal.ROUND_HALF_UP).toString());
        }
    }
}
